/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    startup.S
 *  @brief   startup file. Should use with
 *           GCC for E906 Processors
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/
/* #include "autoconf.h" */
/* #include "drv.h" */
/* #include "irq.h" */

.section .vectors, "aw", @progbits
	/* 异常入口64字节对齐 */
	.align  6
	.globl  __Vectors
	.type   __Vectors, @object
__Vectors:
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler

	/* External interrupts */
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	.long   Default_IRQHandler
	/*.long   Default_IRQHandler*/
	/*.long   Default_IRQHandler*/

	/*support irq id up to 207*/
	.size   __Vectors, .-__Vectors

	.text
	.align  2

_start:
	.text
	.align  2
	.globl  Reset_Handler
	.type   Reset_Handler, %function

Reset_Handler:
	/* 禁止机器模式所有中断 */
	csrc    mstatus, 8
.option push
.option norelax
	/* gp 寄存器, 全局变量基地址 */
	la      gp, __global_pointer$
.option pop
	/**
	 * RISCV中断系统分为NMI/异常/软件中断/定时器中断/外部中断；
	 */
	/* 设置异常向量表基地址和模式 */

	la      a0, Default_Handler

	/**
	 * E906模式位固定为2’b11，而clicintattr[i].shv可配置对应中断为向量/非向量模式
	 * = 0(非矢量模式), 异常和中断入口地址为mtvec[31:6] << 6
	 * = 1 clic vector mode(矢量模式), 异常入口地址为mtvec[31:6] << 6, 中断入口地址MEM[mtvt[31:0] + 4 * 中断ID]
	 * MTVEC寄存器MODE[1:0]是2’b00时, 异常和中断都统一使用mtvec[31:6] << 6地址作为异常入口地址
	 * MTVEC寄存器MODE[1:0]是2’b01时, 异常仍使用BASE地址作为入口地址, 中断使用(BASE << 2 + 4 * 中断ID)的值作为入口地址
	 * 硬件配置CLIC模式时, MODE[1:0]新增2’b10和2’b11配置. 处理器在该两种模式下, 异常入口地址会被约束为64字节对齐
	 * 当MODE[1:0]是2’b10时, 保留
	 * 当MODE[1:0]是2’b11时, CPU使用MTVEC[31:6] << 6作为异常的服务程序入口地址并跳转执行,
	 * 硬件矢量中断模式下, CPU首先使用MTVT + 4* 中断ID 为地址, 取出中断服务程序入口地址,
	 * 非硬件矢量中断模式下CPU, 使用MTVEC[31:6]<<6 作为中断服务程序入口地址并跳转执行
	 */
	ori     a0, a0, 3
	csrw    mtvec, a0

	/* 浮点控制寄存器和通用寄存器处于初始化状态 */
	li      a0, 0x2000
	csrs    mstatus, a0

	/* 机器模式矢量中断基址寄存器 */
	la      a0, __Vectors

	csrw    mtvt, a0

	/* 处理器处于精确异常工作模式 */
	la      a0, 0x100000
	csrw    mhint, a0

	/* 设置栈指针 */
	/*la      sp, g_base_taskstack*/
	    /* 设置栈指针 */
    la      sp, g_top_irqstack
    csrw    mscratch, sp

    /* Load data section 代码加载 */
    la      a0, __erodata
    la      a1, __data_start__
    la      a2, __data_end__
    bgeu    a1, a2, 2f
1:
    lw      t0, (a0)
    sw      t0, (a1)
    addi    a0, a0, 4
    addi    a1, a1, 4
    bltu    a1, a2, 1b
2:

    /* Clear bss section RAM初始化 */
    la      a0, __bss_start__
    la      a1, __bss_end__
    bgeu    a0, a1, 2f
1:
    sw      zero, (a0)
    addi    a0, a0, 4
    bltu    a0, a1, 1b
2:

	/**
	 * jalr: 跳转到寄存器保存的地址, 并将下一条指令的地址保存到x1(ra)
	 * jal: 跳转PC+offset, 并将下一条指令的地址保存到x1(ra)
	 * j: 跳转PC+offset, 不保存下一条指令的地址到x1(ra)
	 */

	/* 直接跳转执行SystemInit函数, 保存下条指令到x1(ra) */
	jal     SystemInit

	jal     Drv_Init

	jal     main

	.size   Reset_Handler, .-Reset_Handler

__exit:
	j __exit
/*
.section .stack

	.align  3
	.global g_top_irqstack
	.global g_base_irqstack
	.global g_top_taskstack
	.global g_base_taskstack
g_top_irqstack:
	.space  2048
g_base_irqstack:
g_top_taskstack:
	.space  4096
g_base_taskstack:*/
.section .bss

    .align  3
    .global g_base_irqstack
    .global g_top_irqstack
g_base_irqstack:
    .space 4098
g_top_irqstack:
